#include <config.h>
#include <debug.h>
#include <header.h>
#include <rules.h>
#include <xml_util.h>

#include "gui.h"
#include "language.h"

static int selected_proto = IPPROTO_TCP;
static int selected_action = NF_ACCEPT;
static GtkWidget *entry_desc = NULL;
static GtkWidget *entry_localport_from = NULL;
static GtkWidget *entry_localport_to = NULL;
static GtkWidget *entry_remoteport_from = NULL;
static GtkWidget *entry_remoteport_to = NULL;

static void func_for_response(GtkDialog *dialog, gint response_id, gpointer user_data);
static void proto_menu_select(GtkWidget *item, int protocol);
static void action_menu_select(GtkWidget *item, int action);
void show_add_rule_dialog(void)
{
  GtkWidget *dialog = NULL;
  GtkWidget *hbox_rule_desc = NULL;
  GtkWidget *hbox_proto = NULL;
  GtkWidget *hbox_port = NULL;
  GtkWidget *frame_desc = NULL;
  GtkWidget *label_desc = NULL;
  GtkWidget *label_proto = NULL;
  GtkWidget *optionmenu_proto =NULL;
  GtkWidget *menu_proto = NULL;
  GtkWidget *label_action = NULL;
  GtkWidget *optionmenu_action =NULL;
  GtkWidget *menu_action = NULL;
  GtkWidget *item = NULL;
  GtkWidget *frame_localport = NULL;
  GtkWidget *vbox_localport = NULL;
  GtkWidget *hbox_localport_top = NULL;
  GtkWidget *hbox_localport_bottom = NULL;
  GtkWidget *frame_remoteport = NULL;
  GtkWidget *vbox_remoteport = NULL;
  GtkWidget *hbox_remoteport_top = NULL;
  GtkWidget *hbox_remoteport_bottom = NULL;
  GtkWidget *label_from = NULL;
  GtkWidget *label_to = NULL;
  GtkWidget *label_port_desc = NULL;
  dialog = gtk_dialog_new_with_buttons(TEXT_ADD_RULES, GTK_WINDOW(main_window),
                                       GTK_DIALOG_MODAL,
                                       GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
                                       GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
                                       NULL);
  hbox_rule_desc = gtk_hbox_new(FALSE, 0);
  hbox_proto = gtk_hbox_new(FALSE, 0);
  hbox_port = gtk_hbox_new(TRUE, 0);
  frame_desc = gtk_frame_new(TEXT_FRAME_DESC);
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox_rule_desc, FALSE, FALSE, 5);
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox_proto, FALSE, FALSE, 5);
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox_port, FALSE, FALSE, 5);
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame_desc, FALSE, FALSE, 5);
  /*desc*/
  label_desc = gtk_label_new(TEXT_RULE_DESC);
  entry_desc = gtk_entry_new_with_max_length(20);
  gtk_box_pack_start(GTK_BOX(hbox_rule_desc), label_desc, FALSE, FALSE, 5);
  gtk_box_pack_start(GTK_BOX(hbox_rule_desc), entry_desc, FALSE, FALSE, 5);
  /*proto and action*/
  label_proto = gtk_label_new(TEXT_PROTO);
  optionmenu_proto = gtk_option_menu_new();
  menu_proto = gtk_menu_new ();
  item = make_menu_item(TEXT_TCP,
                        G_CALLBACK(proto_menu_select),
                        GINT_TO_POINTER(IPPROTO_TCP));
  gtk_menu_shell_append(GTK_MENU_SHELL(menu_proto), item);
  item = make_menu_item(TEXT_UDP, G_CALLBACK(proto_menu_select), 
                        GINT_TO_POINTER(IPPROTO_UDP));
  gtk_menu_shell_append(GTK_MENU_SHELL(menu_proto), item);
  gtk_option_menu_set_menu(GTK_OPTION_MENU(optionmenu_proto), menu_proto);

  label_action = gtk_label_new(TEXT_ACTION);


  optionmenu_action = gtk_option_menu_new();
  menu_action = gtk_menu_new();
  item = make_menu_item(TEXT_ACCEPT,
                        G_CALLBACK(action_menu_select),
                        GINT_TO_POINTER(NF_ACCEPT));
  gtk_menu_shell_append(GTK_MENU_SHELL(menu_action), item);
  item = make_menu_item(TEXT_DROP, G_CALLBACK(action_menu_select), 
                        GINT_TO_POINTER(NF_DROP));
  gtk_menu_shell_append(GTK_MENU_SHELL(menu_action), item);
  gtk_option_menu_set_menu(GTK_OPTION_MENU(optionmenu_action), menu_action);

  gtk_box_pack_start(GTK_BOX(hbox_proto), label_proto, FALSE, FALSE, 5);
  gtk_box_pack_start(GTK_BOX(hbox_proto), optionmenu_proto, FALSE, FALSE, 10);
  gtk_box_pack_start(GTK_BOX(hbox_proto), label_action, FALSE, FALSE, 10);
  gtk_box_pack_start(GTK_BOX(hbox_proto), optionmenu_action, FALSE, FALSE, 5);
  /*port*/
  frame_localport = gtk_frame_new(TEXT_LOCAL_PORT);
  vbox_localport = gtk_vbox_new(FALSE, 0);
  gtk_container_add(GTK_CONTAINER(frame_localport), vbox_localport);
  hbox_localport_top = gtk_hbox_new(FALSE, 0);
  hbox_localport_bottom = gtk_hbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(vbox_localport), hbox_localport_top, FALSE, FALSE, 5);
  gtk_box_pack_start(GTK_BOX(vbox_localport), hbox_localport_bottom, FALSE, FALSE, 5);
  label_from = gtk_label_new(TEXT_FROM);
  label_to = gtk_label_new(TEXT_TO);
  entry_localport_from = gtk_entry_new_with_max_length(5);
  entry_localport_to = gtk_entry_new_with_max_length(5);
  gtk_box_pack_start(GTK_BOX(hbox_localport_top), label_from, FALSE, FALSE, 5);
  gtk_box_pack_end(GTK_BOX(hbox_localport_top), entry_localport_from,
                   FALSE, FALSE, 5);
  gtk_box_pack_start(GTK_BOX(hbox_localport_bottom), label_to, FALSE, FALSE, 5);
  gtk_box_pack_end(GTK_BOX(hbox_localport_bottom), entry_localport_to,
                   FALSE, FALSE, 5);

  frame_remoteport = gtk_frame_new(TEXT_REMOTE_PORT);
  vbox_remoteport = gtk_vbox_new(FALSE, 0);
  gtk_container_add(GTK_CONTAINER(frame_remoteport), vbox_remoteport);
  hbox_remoteport_top = gtk_hbox_new(FALSE, 0);
  hbox_remoteport_bottom = gtk_hbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(vbox_remoteport), hbox_remoteport_top, FALSE, FALSE, 5);
  gtk_box_pack_start(GTK_BOX(vbox_remoteport), hbox_remoteport_bottom, FALSE, FALSE, 5);
  label_from = gtk_label_new(TEXT_FROM);
  label_to = gtk_label_new(TEXT_TO);
  entry_remoteport_from = gtk_entry_new_with_max_length(5);
  entry_remoteport_to = gtk_entry_new_with_max_length(5);
  gtk_box_pack_start(GTK_BOX(hbox_remoteport_top), label_from, FALSE, FALSE, 5);
  gtk_box_pack_end(GTK_BOX(hbox_remoteport_top), entry_remoteport_from,
                   FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(hbox_remoteport_bottom), label_to, FALSE, FALSE, 5);
  gtk_box_pack_end(GTK_BOX(hbox_remoteport_bottom), entry_remoteport_to,
                   FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(hbox_port), frame_localport, FALSE, FALSE, 5);
  gtk_box_pack_start(GTK_BOX(hbox_port), frame_remoteport, FALSE, FALSE, 5);
  /*port desc frame*/
  label_port_desc = gtk_label_new(TEXT_USER_DEFINED_RULES_DESC);
  gtk_container_add(GTK_CONTAINER(frame_desc), label_port_desc);
  /*misc*/
  gtk_entry_set_width_chars(GTK_ENTRY(entry_localport_from), 5);
  gtk_entry_set_width_chars(GTK_ENTRY(entry_localport_to), 5);
  gtk_entry_set_width_chars(GTK_ENTRY(entry_remoteport_from), 5);
  gtk_entry_set_width_chars(GTK_ENTRY(entry_remoteport_to), 5);
  gtk_window_set_icon_from_file(GTK_WINDOW(dialog), COOLNET_TRAY_ICON, NULL);
  /*connect signal*/
  gtk_signal_connect(GTK_OBJECT(dialog), "response",
                     G_CALLBACK(func_for_response), NULL);

  gtk_widget_show_all(GTK_WIDGET(dialog));
  return;
}
GtkWidget *make_menu_item(gchar     *name,
                          GCallback  callback,
                          gpointer   data )
{
  GtkWidget *item = NULL;

  item = gtk_menu_item_new_with_label(name);
  g_signal_connect(G_OBJECT(item), "activate",
                   callback,(gpointer) data);
  gtk_widget_show(item);

  return item;
}

static void func_for_response(GtkDialog *dialog, gint response_id, gpointer user_data)
{
  const char *desc = NULL;
  const char *localport_from = NULL;
  const char *localport_to = NULL;
  const char *remoteport_from = NULL;
  const char *remoteport_to = NULL;
  char *temp = NULL;
  int lpf_value = 0;
  int lpt_value = 0;
  int rpf_value = 0;
  int rpt_value = 0;
  if (GTK_RESPONSE_APPLY == response_id)
  {
    /*start param check*/
    desc = gtk_entry_get_text(GTK_ENTRY(entry_desc));
    if (0 == strlen(desc))
    {
      popup_error_dialog(GTK_WINDOW(dialog), GTK_MESSAGE_ERROR,
                         TEXT_DESC_CANNOT_BE_NULL);
      return;
    }
    localport_from = gtk_entry_get_text(GTK_ENTRY(entry_localport_from));
    localport_to = gtk_entry_get_text(GTK_ENTRY(entry_localport_to));
    remoteport_from = gtk_entry_get_text(GTK_ENTRY(entry_remoteport_from));
    remoteport_to = gtk_entry_get_text(GTK_ENTRY(entry_remoteport_to));

    if (0 == strlen(localport_from) || 0 == strlen(localport_to)
        || 0 == strlen(remoteport_from) || 0 == strlen(remoteport_to))
    {
      popup_error_dialog(GTK_WINDOW(dialog), GTK_MESSAGE_ERROR,
                         TEXT_PORT_FORMAT_ERROR);
      return;
    }

    temp = (char *)localport_from;
    while (*temp)
    {
      if (!isdigit(*temp))
      {

        popup_error_dialog(GTK_WINDOW(dialog), GTK_MESSAGE_ERROR,
                           TEXT_PORT_FORMAT_ERROR);
        return;
      }
      temp ++;
    }
    temp = (char *)localport_to;
    while (*temp)
    {
      if (!isdigit(*temp))
      {

        popup_error_dialog(GTK_WINDOW(dialog), GTK_MESSAGE_ERROR,
                           TEXT_PORT_FORMAT_ERROR);
        return;
      }
      temp ++;
    }
    temp = (char *)remoteport_from;
    while (*temp)
    {
      if (!isdigit(*temp))
      {

        popup_error_dialog(GTK_WINDOW(dialog), GTK_MESSAGE_ERROR,
                           TEXT_PORT_FORMAT_ERROR);
        return;
      }
      temp ++;
    }
    temp = (char *)remoteport_to;
    while (*temp)
    {
      if (!isdigit(*temp))
      {

        popup_error_dialog(GTK_WINDOW(dialog), GTK_MESSAGE_ERROR,
                           TEXT_PORT_FORMAT_ERROR);
        return;
      }
      temp ++;
    }
    lpf_value = atoi(localport_from);
    lpt_value = atoi(localport_to);
    rpf_value = atoi(remoteport_from);
    rpt_value = atoi(remoteport_to);
    if ((lpf_value > lpt_value) || (rpf_value > rpt_value))
    {
      popup_error_dialog(GTK_WINDOW(dialog), GTK_MESSAGE_ERROR,
                         TEXT_PORT_RANGE_ERROR);
      return;
    }
    /*end param check*/
    /*add xml entry*/
    xml_add_user_defined_rules((xmlChar *)desc, selected_proto,
                               lpf_value, lpt_value,
                               rpf_value, rpt_value,
                               selected_action);
    /*add user-defined rules*/
    add_user_defined_rules(selected_proto,
                           lpf_value, lpt_value,
                           rpf_value, rpt_value,
                           selected_action);
    /*add list_store*/
    add_user_defined_list_store((char *)desc, selected_action, selected_proto,
                                lpf_value, lpt_value, rpf_value, rpt_value);
    gtk_widget_destroy(GTK_WIDGET(dialog));
  }
  else if (GTK_RESPONSE_CLOSE == response_id)
  {
    gtk_widget_destroy(GTK_WIDGET(dialog));
  }
}
static void proto_menu_select(GtkWidget *item, int protocol)
{
  selected_proto = protocol;
}
static void action_menu_select(GtkWidget *item, int action)
{
  selected_action = action;
}
